$title Minimal

* ------------------------------------------------------------------------------
* Simplified CGE model in %-change like ORANI-G, but with only 7 sectors,
* a simplified treatment of taxes, and no margins or multiproduction.
* Laurent Cretegny, CoPS, Monash University, Australia, 2004.
* ------------------------------------------------------------------------------

sets
  user              all users
  ind(user)         industries and commodities
  src               source of commodities
  fac               primary factors;

alias (user,u), (ind,i), (i,o), (src,s), (fac,f);

parameters
  factor(f,i)       wages and profits
  use(o,s,u)        use matrix
  v1ptx(i)          production tax revenue
  v0mtx(o)          import tax revenue
  sigma(o)          Armington elasticities
  sigma1prim(i)     primary factor substitution elasticity
  exp_elast(o)      export demand elasticities;

$gdxin minimal
$load user ind src fac factor use v1ptx v0mtx sigma sigma1prim exp_elast
$gdxin

parameters
  b_usedom(o,u)     domestic use matrix
  b_useimp(o,u)     import use matrix
  b_use(o,u)        aggregated use matrix
  b_factor(f,i)     revenue of primary factors
  b_va(i)           value-added
  b_endow(f)        endowment
  b_output(i)       domestic production
  b_invest          investment
  b_expend          household expenditure 
  b_govexp          government expenditure
  b_export(o)       exports
  b_import(o)       imports (net of tariff)
  b_ty(i)           production tax rate
  b_tm(o)           import tariff rate
  b_py(i)           production price
  b_pm(o)           import price
  b_pwd             world price
  b_bop             balance of payments (surplus)
  b_c               consumption
  b_rw              real wage;

b_usedom(o,u) = use(o,'dom',u);
b_useimp(o,u) = use(o,'imp',u);
b_use(o,u)$(not sameas(u,"exp")) = sum(s, use(o,s,u));

b_factor(f,i) = factor(f,i);
b_va(i) = sum(f, factor(f,i));
b_endow(f) = sum(i, factor(f,i));

b_output(i) = sum(o, b_use(o,i)) + b_va(i) + v1ptx(i);
b_ty(i) = v1ptx(i) / b_output(i);
b_py(i) = 1 - b_ty(i);

b_invest = sum(o, b_use(o,'inv'));
b_expend = sum(o, b_use(o,'hh'));
b_govexp = sum(o, b_use(o,'gov'));

b_export(o) = use(o,'dom','exp');
b_import(o) = sum(u, use(o,'imp',u)) - v0mtx(o);
b_tm(o)$b_import(o) = v0mtx(o) / b_import(o);
b_pwd(o) = 1;
b_pm(o) = b_pwd(o) * (1 + b_tm(o));
b_bop = sum(o, b_export(o) - b_import(o));

b_c = 1;
b_rw = 1;

$ontext
$model:minimal

$sectors:
  y(i)              ! production
  a(o,u)$b_use(o,u) ! Armington index
  v(i)              ! value-added
  m(o)              ! import index
  c                 ! household consumption
  j                 ! aggregate investment
  g                 ! government demand

$commodities:
  pd(i)             ! domestic price of output
  pa(o,u)$b_use(o,u)! Armington price index
  pv(i)             ! price index for value-added
  pl                ! price of labour (wage rate)
  pk(i)             ! price of capital (sector specific)
  pm(o)             ! price of imports
  pfx               ! real exchange rate
  pc                ! consumer price index
  pj                ! price of a unit of investment
  pg                ! price of a unit of government output

$consumers:
  ra                ! representative agent

$auxiliary:
  e(o)              ! export index
  efx               ! total exports in foreign exchange
  bop               ! balance of payments index (surplus)
  upl               ! unemployment index

$prod:y(i)          s:0.0                         ! Excerpt 6, 9  : E_p1tot, E_pA
  o:pd(i)           q:b_output(i)       p:b_py(i)           a:ra      t:b_ty(i)
  i:pa(o,i)         q:b_use(o,i)    
  i:pv(i)           q:b_va(i)

$prod:a(o,u)$b_use(o,u)        s:sigma(o)         ! Excerpt 4 : E_p_s
  o:pa(o,u)         q:b_use(o,u)
  i:pd(o)           q:b_usedom(o,u)
  i:pm(o)           q:b_useimp(o,u)

$prod:v(i)          s:sigma1prim(i)               ! Excerpt 5 : E_p1prim
  o:pv(i)           q:b_va(i)
  i:pl              q:b_factor("lab",i)
  i:pk(i)           q:b_factor("cap",i)

$prod:m(o)                                        ! Excerpt 10 : E_pB
  o:pm(o)           q:(b_import(o)*b_pm(o))
  i:pfx             q:b_import(o)       p:b_pm(o)           a:ra      t:b_tm(o)

$prod:c             s:1.0                         ! Excerpt 7 : E_p3tot
  o:pc              q:b_expend
  i:pa(o,"hh")      q:b_use(o,"hh")

$prod:j
  o:pj              q:b_invest
  i:pa(o,"inv")     q:b_use(o,"inv")

$prod:g
  o:pg              q:b_govexp
  i:pa(o,"gov")     q:b_use(o,"gov")

$demand:ra
  d:pc              q:b_expend
  e:pl              q:b_endow("lab")
  e:pk(i)           q:b_factor("cap",i)
  e:pj              q:-b_invest                   ! Closure : aggregate investment fixed
  e:pg              q:-b_govexp                   ! Closure : government demand fixed
  e:pfx             q:1                           r:efx
  e:pd(o)           q:-b_export(o)                r:e(o)
  e:pfx             q:-b_bop                      r:bop
  e:pl              q:-b_endow("lab")             r:upl

$constraint:e(o)                                  ! Excerpt 8 : E_x4a
  e(o) =e= (pd(o) / (pfx*b_pwd(o)))**(-exp_elast(o));

$constraint:efx
  efx =e= sum(o, e(o)*b_export(o));

$constraint:bop                                   ! Closure : balance of payments free
  c =e= b_c;                                      ! Closure : consumption fixed

$constraint:upl                                   ! Closure : level of employment free
  pl / pc =e= b_rw;                               ! Closure : real wage fixed

$report:
  v:cons(o)                   i:pa(o,"hh")        prod:c

$offtext
$sysinclude mpsgeset minimal

* Initialize levels on auxiliary variables

upl.lo = -inf;
bop.lo = -inf;

upl.l = 0;
bop.l = 1;

e.l(o) = 1;
efx.l = sum(o, b_export(o));

* Fixation of the exchange rate as the numeraire

pfx.fx = 1;

* Benchmark replication

minimal.iterlim = 0;
$include minimal.gen
solve minimal using mcp;
abort$(abs(minimal.objval) gt 1e-4) '*** minimal does not calibrate ! ***';
minimal.iterlim = 10000;

* Counterfactual (10% increase in consumption)

b_c = b_c * 1.1;
b_use(o,'hh') = b_use(o,'hh') * 1.1;
$include minimal.gen
solve minimal using mcp;

* Results

parameters
  res_com           results by commodity in % change from basis
  res_agg           aggregate results in % change from basis; 

res_com('output',o) = (y.l(o) - 1) * 100;
res_com('cons',o)$b_use(o,'hh') = (cons.l(o)/b_use(o,'hh') - 1) * 100;
res_com('import',o) = (m.l(o) - 1) * 100;
res_com('export',o) = (e.l(o) - 1) * 100;
res_com('price',o) = (pd.l(o) - 1) * 100;

res_agg('employ') = - upl.l * 100;
res_agg('ra_inc') = (ra.l/b_expend - 1 ) * 100;

option decimals = 6;
display res_com, res_agg;
